import "package:flutter/cupertino.dart";

abstract final class Stacker {
  static final GlobalKey<NavigatorState> key = GlobalKey();
  static NavigatorState state = key.currentState!;
  static BuildContext context = key.currentContext!;

  static void pop<T extends Object?>([T? result]) => state.pop<T>(result);

  static Future<T?> popAndPush<T extends Object?>(Widget page) async {
    pop();
    T? popped = await push<T>(page);
    return popped;
  }

  static Future<T?> push<T extends Object?>(Widget page) async {
    T? popped =
        await state.push<T>(CupertinoPageRoute(builder: (context) => page));
    return popped;
  }

  static Future<T?> pushNamed<T extends Object?>(String path, {Object? arguments}) async {
    T? popped =
        await state.pushNamed<T>(path, arguments: arguments);
    return popped;
  }

  static Future<T?> pushAndRemoveUntil<T extends Object?>(
    Widget page, [
    bool Function(Route<dynamic>)? predicate,
  ]) async {
    T? popped = await state.pushAndRemoveUntil(
      CupertinoPageRoute(builder: (context) => page),
      predicate ?? (route) => false,
    );
    return popped;
  }

  static Future<T?> pushNamedAndRemoveUntil<T extends Object?>(
    String path,
    bool Function(Route<dynamic>)? predicate,
    { Object? arguments, }
  ) async {
    T? popped = await state.pushNamedAndRemoveUntil(
      path,
      predicate ?? (route) => false,
      arguments: arguments,
    );
    return popped;
  }

  static Future<T?> pushReplacement<T extends Object?, TO extends Object?>(
    Widget page, {
    TO? result,
  }) async {
    T? popped = await state.pushReplacement<T, TO>(
      CupertinoPageRoute(builder: (context) => page),
      result: result,
    );
    return popped;
  }

  static Future<T?> pushReplacementNamed<T extends Object?, TO extends Object?>(
    String path, {
    TO? result,
    Object? arguments,
  }) async {
    T? popped = await state.pushReplacementNamed<T, TO>(
      path,
      result: result,
      arguments: arguments,
    );
    return popped;
  }

  static void popUntil<T extends Object?>(
    bool Function(Route<dynamic>)? predicate,
  ) {
    state.popUntil(
      predicate ?? (route) => false,
    );
  }

  static Future<T?> popAndPushNamed<T extends Object?, TO extends Object?>(
      String path, {
        TO? result,
        Object? arguments,
      }) async {
    T? popped = await state.popAndPushNamed<T, TO>(
      path,
      result: result,
      arguments: arguments,
    );
    return popped;
  }


}